load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_library", "mongo_cc_unit_test")

package(default_visibility = ["//visibility:public"])

exports_files(
    glob([
        "*.h",
    ]),
)

OTEL_TARGET_COMPATIBLE_WITH = select({
    "//bazel/config:build_otel_enabled": [],
    "//conditions:default": ["@platforms//:incompatible"],
})

GRPC_TARGET_COMPATIBLE_WITH = select({
    "//bazel/config:build_grpc_enabled": [],
    "//conditions:default": ["@platforms//:incompatible"],
})

idl_generator(
    name = "trace_settings_gen",
    src = "trace_settings.idl",
)

idl_generator(
    name = "tracing_feature_flag_gen",
    src = "tracing_feature_flag.idl",
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

mongo_cc_library(
    name = "tracing_enablement",
    srcs = [
        "tracing_enablement.cpp",
        ":tracing_feature_flag_gen",
    ],
    hdrs = [
        "tracing_enablement.h",
    ],
    deps = [
        "//src/mongo/db:server_base",
        "//src/mongo/db:service_context",
    ],
)

mongo_cc_library(
    name = "tracing_utils",
    srcs = [
        "tracing_utils.cpp",
    ],
    hdrs = [
        "tracing_utils.h",
    ],
    deps = [
        "//src/mongo/db:server_base",
        "//src/third_party/opentelemetry-cpp/api",
    ],
)

mongo_cc_library(
    name = "tracing_initialization",
    deps = [
        ":tracing_initialization_base",
    ] + select(
        {
            "@//bazel/config:build_otel_enabled": [
                ":tracing_initialization_impl",
            ],
            "//conditions:default": [],
        },
    ),
)

mongo_cc_library(
    name = "tracing_initialization_base",
    srcs = [
        ":trace_settings_gen",
    ],
    hdrs = [
        "trace_initialization.h",
    ],
    deps = [
        "//src/mongo/db:server_base",
    ],
)

mongo_cc_library(
    name = "tracing_initialization_impl",
    srcs = [
        "trace_initialization.cpp",
        "tracer_provider_service.cpp",
    ],
    hdrs = [
        "tracer_provider_service.h",
    ],
    target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
    deps = [
        ":tracing_initialization_base",
        "//src/third_party/opentelemetry-cpp/exporters/otlp:otlp_file_exporter",
        "//src/third_party/opentelemetry-cpp/exporters/otlp:otlp_http_exporter",
        "//src/third_party/opentelemetry-cpp/sdk/src/trace",
        "//src/third_party/opentelemetry-proto:resource_proto_cc",
        "//src/third_party/opentelemetry-proto:trace_proto_cc",
        "//src/third_party/protobuf",
    ],
)

mongo_cc_library(
    name = "span_telemetry_context",
    srcs = [
        "//src/mongo/otel/traces/span:span_telemetry_context_impl.cpp",
    ],
    hdrs = [
        "//src/mongo/otel/traces/span:span_telemetry_context_impl.h",
    ],
    deps = [
        ":tracing_utils",
        "//src/mongo/db:server_base",
        "//src/mongo/otel:otel_base",
    ],
)

mongo_cc_library(
    name = "telemetry_context_serialization",
    deps = [
        ":telemetry_context_serialization_header",
    ] + select(
        {
            "@//bazel/config:build_otel_enabled": [
                ":telemetry_context_serialization_impl",
            ],
            "//conditions:default": [],
        },
    ),
)

mongo_cc_library(
    name = "telemetry_context_serialization_header",
    hdrs = [
        "telemetry_context_serialization.h",
    ],
    deps = [
        "//src/mongo/otel:otel_base",
    ],
)

mongo_cc_library(
    name = "telemetry_context_serialization_impl",
    srcs = [
        "bson_text_map_carrier.cpp",
        "telemetry_context_serialization.cpp",
    ],
    hdrs = [
        "bson_text_map_carrier.h",
    ],
    target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
    deps = [
        ":span_telemetry_context",
        ":telemetry_context_serialization_header",
        "//src/mongo/db:server_base",
        "//src/third_party/opentelemetry-cpp/api",
    ],
)

# Library for public facing tracing API used by the larger codebase.
mongo_cc_library(
    name = "tracing",
    deps = [
        "//src/mongo/base:system_error",
        "//src/mongo/db:server_base",
        "//src/mongo/otel:otel_base",
    ] + select(
        {
            "@//bazel/config:build_otel_enabled": [
                ":tracing_internal",
            ],
            "//conditions:default": [],
        },
    ),
)

# Private implementation for the tracing library. These files are only built
# when OTEL is enabled and must only be included from regions where
# MONGO_CONFIG_OTEL is defined.
mongo_cc_library(
    name = "tracing_internal",
    srcs = [
        "//src/mongo/otel/traces/span:span.cpp",
    ],
    target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
    deps = [
        ":span_telemetry_context",
        ":tracing_initialization",
        "//src/mongo/base:system_error",
        "//src/mongo/db:server_base",
        "//src/mongo/db:service_context",
        "//src/mongo/otel:otel_base",
        "//src/third_party/opentelemetry-cpp/api",
    ],
)

mongo_cc_library(
    name = "tracing_test_util",
    srcs = [
        "mock_exporter.cpp",
    ],
    target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
    deps = [
        "//src/mongo/db:server_base",
        "//src/mongo/db:service_context_test_fixture",
        "//src/third_party/opentelemetry-cpp/api",
        "//src/third_party/opentelemetry-cpp/sdk/src/trace",
    ],
)

mongo_cc_unit_test(
    name = "tracing_test",
    srcs = [
        "bson_text_map_carrier_test.cpp",
        "telemetry_context_serialization_test.cpp",
        "trace_initialization_test.cpp",
        "//src/mongo/otel/traces/span:span_telemetry_context_impl_test.cpp",
        "//src/mongo/otel/traces/span:span_test.cpp",
    ],
    tags = [
        "mongo_unittest_fourth_group",
        "tracing_test",
    ],
    target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
    deps = [
        ":tracing",
        ":tracing_test_util",
        "//src/mongo/db:service_context_test_fixture",
        "//src/mongo/idl:server_parameter_test_util",
        "//src/mongo/otel",
        "//src/third_party/opentelemetry-cpp/api",
    ],
)

mongo_cc_unit_test(
    name = "grpc_tracing_test",
    srcs = [
        "grpc_tracing_test.cpp",
    ],
    tags = [
        "mongo_unittest_fourth_group",
        "tracing_test",
    ],
    target_compatible_with = GRPC_TARGET_COMPATIBLE_WITH,
    deps = [
        ":tracing",
        "//src/mongo/db:service_context_test_fixture",
        "//src/third_party/opentelemetry-cpp/exporters/otlp:otlp_grpc_exporter",
    ],
)
